from odoo import fields, models, api, _
from odoo.tools import float_round
from decimal import Decimal, getcontext, ROUND_HALF_UP

getcontext().prec = 16  # 設定 Decimal 計算精度


class ShippingInstructionsLine(models.Model):
    _inherit = 'ship.instructions.line'

    s_product_metre = fields.Float(string='Product Metre(Pcs)', compute="_compute_product_metre", store=True, digits=(16, 10))
    s_product_metre_spcs = fields.Float(string='Single Pcs Metre', compute="_compute_product_metre", store=True, digits=(16, 10))

    @api.depends('packed_qty')
    def _compute_product_metre(self):
        PRECISION = 10
        for o_row in self:
            # 將輸入值都轉為 Decimal（避免浮點誤差）
            try:
                setl = Decimal(str(
                    o_row.product_id.product_tmpl_id.uom_value_ids.filtered(lambda x: x.uom_id.code == 'SETL').uom_value or 1.0
                ))
                setw = Decimal(str(
                    o_row.product_id.product_tmpl_id.uom_value_ids.filtered(lambda x: x.uom_id.code == 'SETW').uom_value or 1.0
                ))
                set_val = Decimal(str(
                    o_row.product_id.product_tmpl_id.uom_value_ids.filtered(lambda x: x.uom_id.code == 'SET').uom_value or 1.0
                ))
                packed_qty = Decimal(str(o_row.packed_qty or 0.0))
            except Exception:
                o_row.s_product_metre = 0.0
                o_row.s_product_metre_spcs = 0.0
                continue

            if set_val == 0:
                o_row.s_product_metre = 0.0
                o_row.s_product_metre_spcs = 0.0
                continue

            # 精確計算單個 pcs 面積
            raw_spcs = (setw * setl / Decimal('1000000')) / set_val

            # 計算總面積
            raw_total = raw_spcs * packed_qty

            # 四捨五入處理（保留 10 位小數）
            spcs_value = raw_spcs.quantize(Decimal('1.' + '0' * PRECISION), rounding=ROUND_HALF_UP)
            total_value = raw_total.quantize(Decimal('1.' + '0' * PRECISION), rounding=ROUND_HALF_UP)

            # 儲存到 float 欄位
            o_row.s_product_metre_spcs = float(spcs_value)
            o_row.s_product_metre = float(total_value)
